package com.qipay.admin.sp.controller;

import com.qipay.admin.BaseController;
import com.qipay.admin.login.AuthPassport;
import com.qipay.admin.sp.vo.SpDTO;
import com.qipay.admin.sp.vo.SpUserDTO;
import com.qipay.baas.model.*;
import com.qipay.core.entity.Pagination;
import com.qipay.core.entity.Result;
import com.qipay.core.entity.ValueObject;
import com.qipay.core.help.BeanHelper;
import com.qipay.core.help.ResultHelper;
import com.qipay.core.qrcode.QRCodeUtils;
import com.qipay.mapper.*;
import com.qipay.order.service.OrderService;
import com.qipay.order.vo.OrderListItem;
import com.qipay.security.UserDetailsServiceImpl;
import com.qipay.sp.SpChannelService;
import com.qipay.sp.SpService;
import com.qipay.sp.SpUserService;
import com.qipay.sp.dto.SpUserOrderListDto;
import com.qipay.utils.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

@Controller
@RequestMapping("/spUser")
public class SpUserController extends BaseController {
    private final Log logger = LogFactory.getLog(this.getClass());
    @Autowired
    SpUserService spUserService;
    @Autowired
    SpUserMapper spUserMapper;
    @Autowired
    SpChannelService spChannelService;

    @Autowired
    SpService spService;

    @Autowired
    OrderService orderService;
    @Autowired
    CpAccountTradlogMapper cpAccountTradlogMapper;

    @Value("${qrcode.static.path}")
    protected String qrcodePath;

    /**
     * 查询供号商,以sp,user,反查出User,
     *
     * @param loginUser
     * @return
     */
    @AuthPassport(key = "admin")
    @RequestMapping(value = {"/query"}, method = RequestMethod.GET)
    public ModelAndView detail(
            @RequestParam(value = "p", required = false, defaultValue = "1") int p,
            @RequestParam(value = "pz", required = false, defaultValue = "10") int pz,
            @AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser
    ) {
        Pagination pagination = Pagination.instance(p, pz);
        List<ValueObject> query = spUserService.query(pagination);
        ModelAndView view = createModelAndView("spuser-list");
        List<SpUserDTO> spUserDTOS = BeanHelper.valueObjectToBean(query, SpUserDTO.class);
        String order_fee_sql = "select IFNULL(SUM(o.amount),0) as amount,IFNULL(SUM(o.advance_amount),0) as advance_amount,su.`name` as description from sp_user su LEFT JOIN `order` o ON su.`name`=o.description AND o.state=3 GROUP BY su.`name`" ;
        List<OrderListItem> orderListItems = orderService.listBy(order_fee_sql,"su.id asc");

        String chong_zhi_sql = "select su.id as cp_id, IFNULL(SUM(cat.amount),0) as amount from sp_user su LEFT JOIN cp_account_tradlog cat on su.id = cat.cp_id GROUP BY su.id";
        List<CpAccountTradlog>cpAccountTradlogs = cpAccountTradlogMapper.listGroup(chong_zhi_sql,"su.id asc");
        if(spUserDTOS!=null&&spUserDTOS.size()>0){
            for (int i=0;i<spUserDTOS.size();i++){
                Integer amount = cpAccountTradlogs.get(i).getAmount();
                Integer usedAmount = orderListItems.get(i).getAmount()-orderListItems.get(i).getAdvanceAmount();
                spUserDTOS.get(i).setAmount(amount-usedAmount);
            }
        }

        view.addObject("spUsers", spUserDTOS);
        view.addObject("page", pagination);
        return view;
    }

    /**
     * 删除供号商,该供号商下面的没有SP,否则抛出异常
     *
     * @param loginUser
     * @return
     */
    @AuthPassport(key = "admin")
    @RequestMapping(value = {"/delete"}, method = RequestMethod.POST)
    @ResponseBody
    public Result<String> delete(@RequestParam(value = "name", required = true) String name,
                                 @AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser
    ) {
        Result<String> resultSample = new Result<String>();

        try {
            SpUserDTO spUserDTO = new SpUserDTO();
            int status = spUserService.delete(name);
            return ResultHelper.success("删除成功");
        } catch (RuntimeException e) {
            return ResultHelper.error(e.getMessage());
        }
    }

    /**
     * 新增供号商
     * @param loginUser
     * @return
     */
    @AuthPassport(key = "admin")
    @RequestMapping(value = {"/add"}, method = RequestMethod.POST)
    @ResponseBody
    public Result<String> userSave(
            @RequestParam(value = "spUserName", required = true) String spUserName,
            @RequestParam(value = "feeRate", required = true) BigDecimal feeRate,
            @AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser) {

        Result<String> resultSample = new Result<String>();

        try {
            SpUserDTO spUserDTO = new SpUserDTO();
            int status = spUserService.add(spUserName,feeRate.divide(new BigDecimal("100")));
            return ResultHelper.success("添加成功");
        } catch (RuntimeException e) {
            return ResultHelper.error(e.getMessage());
        }
    }

    /**
     * 查询当前供号商下的,支付账号
     *
     * @param loginUser
     * @return
     */
    @RequestMapping(value = {"/spListQuery"}, method = RequestMethod.GET)
    @ResponseBody
    public ModelAndView spListQuery(
            @RequestParam(value = "from", required = false) String from,
            @RequestParam(value = "to", required = false) String to,
            @RequestParam(value = "p", required = false, defaultValue = "0") int p,
            @RequestParam(value = "pz", required = false, defaultValue = "10") int pz,
            @AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser) throws UnsupportedEncodingException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        if (StringUtils.isBlank(from) || StringUtils.isBlank(to)) {
            Calendar calendar = Calendar.getInstance();
            from = format.format(calendar.getTime())+" 00:00";
            calendar.add(Calendar.DAY_OF_YEAR, 1);
            to = format.format(calendar.getTime())+" 00:00";
        }

        Pagination pagination = Pagination.instance(p, pz);
        List<Sp> spList = spService.findBySpUser(loginUser.getUsername(), pagination);
        Long total = orderService.sumOrderBySpUser(loginUser.getUsername(),from,to);
        if (spList!=null&&spList.size()>0){
            for (Sp sp:spList){
                Pagination pagination1 = Pagination.instance(1, 10000);
                SpUserOrderListDto res = spUserService.selectSpOrderList(sp.getId().intValue(), from, to, pagination1);
                sp.setCardNo(res.getTotalAmount().toString());
            }
        }
        String query = "?";
        Map<String, String> params = new HashMap<>();
        if (StringUtils.isNotBlank(from)) {
            query += String.format("&from=%s", URLEncoder.encode(from.toString(), "utf8"));
            params.put("from", from.toString());
        }
        if (StringUtils.isNotBlank(to)) {
            query += String.format("&to=%s", URLEncoder.encode(to.toString(), "utf8"));
            params.put("to", to.toString());
        }

        ModelAndView view = createModelAndView("spuser-splist");
        view.addObject("pagination", pagination);
        view.addObject("query", query);
        view.addObject("spList", spList);
        view.addObject("total",  new BigDecimal(total).divide(new BigDecimal(100)).toString());
        view.addObject("params", params);
        return view;
    }
    /**
     *修改支付宝号
     * @return
     */
    @RequestMapping(value = {"/{id:[\\d]+}"}, method = RequestMethod.GET)
    public ModelAndView detail(@AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser,
                               @PathVariable @NotNull int id) {
        ModelAndView view = createModelAndView("spuser-spdetail");
        if (id > 0) {
            Sp sp = spService.get(id);
            if (sp != null && sp.getId() != null) {
                view.addObject("isadd", "0");
                view.addObject("detail", sp);
                SpUser spUser = spUserMapper.selectByPrimaryKey(Integer.valueOf(loginUser.getUsername()));
                view.addObject("spUser", spUser);
                return view;
            }
        }
        return new ModelAndView("redirect:/spUser/spListQuery");
    }
    /**
     *添加支付宝号
     * @return
     */
    @RequestMapping(value = {"/add/alipay"}, method = RequestMethod.GET)
    public ModelAndView add(@AuthenticationPrincipal UserDetailsServiceImpl.LoginUserDetails loginUser) {
        ModelAndView view = createModelAndView("spuser-spdetail");
        view.addObject("isadd", "1");
        SpUser spUser = spUserMapper.selectByPrimaryKey(Integer.valueOf(loginUser.getUsername()));
        view.addObject("spUser", spUser);
        return view;
    }
    @Value("${sp.chanel.FeeRecharge}")
    protected String feeRecharge;
    @Value("${sp.chanel.Quota}")
    protected String Quota;
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public String save(SpDTO dto) {

        if (dto != null) {
            Sp sp = null;
            if (dto.getId() != null && dto.getId() > 0) {
                sp = spService.get(dto.getId().intValue());
                BeanUtils.copyProperties(dto, sp);
                sp.setUpdateDate(new Date());
                spService.update(sp);
            } else {
                sp = new Sp();
                BeanUtils.copyProperties(dto, sp);
                sp.setCreateDate(new Date());
                sp.setUpdateDate(new Date());
                sp.setDeleteFlag((byte) 0);
                spService.insert(sp);

                //直接增加一个spchanel
                SpChannel db = new SpChannel();
                db.setSpId(sp.getId());
                db.setChannelType((byte)20);
                db.setFeeRecharge(new BigDecimal(feeRecharge));
                db.setState((byte)0);
                db.setQuota(Quota);
                db.setUpdateDate(new Date());
                db.setCreateDate(new Date());
                spChannelService.insert(db);
            }
        }
        return "redirect:/spUser/spListQuery";
    }
    /**
     * 查询当前供号商下的,某个支付账号的流水
     * 以json返回,
     * @return
     */
    @RequestMapping(value = {"/code/detail"}, method = RequestMethod.GET)
    @ResponseBody
    public Result codeDetail(
            @RequestParam(value = "spId", required = true) Long spId){
        AlipayTransferLogExample alipayTransferLogExample = new AlipayTransferLogExample();
        alipayTransferLogExample.createCriteria().andSpIdEqualTo(spId);
        List<AlipayTransferLog> alipayTransferLogs = alipayTransferLogMapper.selectByExample(alipayTransferLogExample);
        if(alipayTransferLogs==null||alipayTransferLogs.size()==0){
            //更改二维码状态
            Sp sp = spService.get(spId.intValue());
            sp.setFailReason(null);
            spService.update(sp);
        }

        return ResultHelper.success("查询成功", alipayTransferLogs);
    }
    /**
     * 查询当前供号商下的,某个支付账号的流水
     * 以json返回,
     * @return
     */
    @RequestMapping(value = {"/code/delete"}, method = RequestMethod.DELETE)
    @ResponseBody
    public Result codeDelete(
            @RequestParam(value = "id", required = true) Long id){
        alipayTransferLogMapper.deleteByPrimaryKey(id);
        return ResultHelper.success("删除成功", null);
    }
    /**
     * 跳转二维码页面
     * @return
     */
    @AuthPassport(key = "admin")
    @RequestMapping(value = {"/personCode/toAdd"})
    public ModelAndView toAdd() {
        ModelAndView view = createModelAndView("add-person-alicode");
        return view;
    }

    @Autowired
    AlipayTransferLogMapper alipayTransferLogMapper;
    @Autowired
    HolidayMapper holidayMapper;
    /**
     * 上传二维码，先手动上传到对应的文件夹，这里直接从文件夹读取，成功与否返回前端
     * @return
     */
    @RequestMapping(value = {"/personCode/add"}, method = RequestMethod.POST)
    @ResponseBody
    public Result add(
            @RequestParam(value = "spId", required = true) Long spId) {
        int failNums = 0;
        File file = new File(qrcodePath+spId);
        File [] files = file.listFiles();
        if(files==null){
            return ResultHelper.success("请先上传二维码，再进行解析", null);
        }
        for (int i = 0; i < files.length; i++){
            File file1 = files[i];
            String fileName = file1.getName();
            String result = QRCodeUtils.getQRCodeUrl(file1);
            /*变为黑白图片，再进行解析
            if(StringUtils.isBlank(result)){
                QRCodeUtils.changeImge(file1);
                result = QRCodeUtils.getQRCodeUrl(file1);
            }*/
            if (StringUtils.isBlank(result)){
                failNums++;
                //两次解析失败，则保存在日志
                Holiday holiday = new Holiday();
                holiday.setDate(DateUtils.sdf.format(new Date()));
                holiday.setName(spId+"--"+fileName+"--解析失败");
                holiday.setIsHoliday((byte)99);
                holidayMapper.insert(holiday);
            }else {
                //保存在二维码调用表
                String type = null;
                if(fileName.indexOf(".jpg")!=-1)type = ".jpg";
                else type = ".png";

                String name = fileName.split(type)[0];//可能是金额，也可能是none，表示任意金额
                Integer amount = null;
                if (isInteger(name)){
                    amount = new BigDecimal(name).multiply(new BigDecimal("100")).intValue();
                }else {
                    amount = 0;//任意金额的码，金额标注为0
                }
                //根据spId和amount进行校验，保持唯一
                AlipayTransferLogExample alipayTransferLogExample = new AlipayTransferLogExample();
                alipayTransferLogExample.createCriteria().andSpIdEqualTo(spId).andAmountEqualTo(amount);
                List<AlipayTransferLog> alipayTransferLogs = alipayTransferLogMapper.selectByExample(alipayTransferLogExample);
                if(alipayTransferLogs!=null&&alipayTransferLogs.size()>0){
                    alipayTransferLogs.stream().forEach(alipayTransferLog -> {
                        alipayTransferLogMapper.deleteByPrimaryKey(alipayTransferLog.getId());
                    });
                }

                AlipayTransferLog alipayTransferLog = new AlipayTransferLog();
                alipayTransferLog.setAmount(amount);
                alipayTransferLog.setSpId(spId);
                alipayTransferLog.setTradeNo(result);//url
                alipayTransferLog.setCreateTime(new Date());
                alipayTransferLogMapper.insert(alipayTransferLog);

            }
            logger.info(fileName+":"+result);

        }

        return ResultHelper.success("总数量"+files.length+",失败:"+failNums, null);
    }

    //判断是不是数字
    private boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

}
